package com.example.ktpermissionx.activity

import android.app.Activity
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.database.Cursor
import android.graphics.Bitmap
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.ContactsContract
import android.provider.MediaStore
import android.widget.ArrayAdapter
import android.widget.ImageView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import com.baidu.location.BDAbstractLocationListener
import com.baidu.location.BDLocation
import com.baidu.location.LocationClient
import com.baidu.location.LocationClientOption
import com.example.ktpermissionx.RepoAdapter
import com.example.ktpermissionx.ui.main.MainViewModel
import com.lxj.xpopup.XPopup
import com.lxj.xpopup.interfaces.OnConfirmListener
import com.lxj.xpopup.interfaces.OnSelectListener
import com.permissionx.guolindev.PermissionX

const val CAMERA = 1
const val PHOTO_ALBUM = 2
const val PHONE = 3
lateinit var imageView: ImageView
var adapter: ArrayAdapter<String>? = null
lateinit var locationClient:LocationClient
lateinit var mContext:Context
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding = com.example.ktpermissionx.databinding.ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        imageView=binding.image
        mContext=this
        PermissionX.init(this)
            .permissions(android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.READ_EXTERNAL_STORAGE)
            .request { allGranted, grantedList, deniedList ->
                if (allGranted){

                }else{

                }
            }

        binding.btn1.setOnClickListener {
            PermissionX.init(this)
                    .permissions(android.Manifest.permission.CAMERA)
                    .request { allGranted, grantedList, deniedList ->
                        if (allGranted){
                            XPopup.Builder(this).asBottomList(null, arrayOf("相机", "相册"), OnSelectListener { position, text ->
                                if (position == 0) {
                                    takePhoto()
                                } else if (position == 1) {
                                    doPickImageFromSystem()
                                }
                            }).show()
                        }else{

                        }
                    }
        }
        binding.btn2.setOnClickListener {
            PermissionX.init(this)
                    .permissions(android.Manifest.permission.READ_CONTACTS, android.Manifest.permission.CALL_PHONE)
                    .request { allGranted, grantedList, deniedList ->
                        if (allGranted){
                            readContacts()
                        }else{

                        }
                    }
        }
        binding.btn3.setOnClickListener {
            PermissionX.init(this)
                    .permissions(android.Manifest.permission.ACCESS_FINE_LOCATION,android.Manifest.permission.ACCESS_COARSE_LOCATION)
                    .request { allGranted, grantedList, deniedList ->
                        if (allGranted){
                            initLocationOption()
                        }else{

                        }
                    }
        }
        binding.btn4.setOnClickListener {
            PermissionX.init(this)
                    .permissions(android.Manifest.permission.RECORD_AUDIO)
                    .explainReasonBeforeRequest()
                    .onExplainRequestReason { scope, deniedList ->
                        scope.showRequestReasonDialog(deniedList,"麦克风权限必须打开!","明白了")
                    }
                    .request { allGranted, grantedList, deniedList ->
                        if (allGranted){
                            XPopup.Builder(mContext).asLoading("录音中").show()
                        }else{

                        }
                    }
        }

/*        典型场景举例：
        1、制定学习计划、旅行日程；
        2、火车票预订、旅行预订；
        3、生日、会议等重要事件日程提醒；*/
        binding.btn5.setOnClickListener {
            PermissionX.init(this)
                    .permissions(android.Manifest.permission.READ_CALENDAR,android.Manifest.permission.WRITE_CALENDAR)
                    .explainReasonBeforeRequest()
                    .onExplainRequestReason { scope, deniedList ->
                        scope.showRequestReasonDialog(deniedList,"日历权限必须打开!","明白了")
                    }
                    .request { allGranted, grantedList, deniedList ->
                        if (allGranted){

                        }else{

                        }
                    }
        }
        binding.btn6.setOnClickListener {
            PermissionX.init(this)
                    .permissions(android.Manifest.permission.SEND_SMS)
                    .request { allGranted, grantedList, deniedList ->
                        if (allGranted){
                            Toast.makeText(this,"发送成功",Toast.LENGTH_SHORT).show()
                        }else{

                        }
                    }
        }
        binding.btn7.setOnClickListener {
            val intent = Intent(this, Paging3Activity::class.java)
            startActivity(intent)
        }
    }

    fun readContacts() {
        var cursor: Cursor? = null
        var map= hashMapOf<String, String>()
        try{
            cursor = contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null)
            if(cursor != null) {
                while(cursor.moveToNext()) {
                    var displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))
                    var number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER))
                    map.put(number, displayName)
                }
                var stringArray = arrayOfNulls<String>(map.size)
                var stringNumber = arrayOfNulls<String>(map.size)
                var i=0
                for ((key, value) in map){
                    stringArray[i]="$value:$key"
                    stringNumber[i]="$key"
                    i++
                }
                XPopup.Builder(this)
                    .asBottomList("联系人", stringArray, OnSelectListener { position, text ->
                        stringNumber.get(position)?.let { call(it) }
                    }).show()
                adapter?.notifyDataSetChanged()
            }
        }catch (e: Exception) {
            e.printStackTrace()
        }finally {
            if(cursor != null) {
                cursor.close()
            }
        }
    }

    private fun call(phone: String) {
        try {
            val intent = Intent(Intent.ACTION_CALL)
            intent.data = Uri.parse("tel:$phone")
            startActivity(intent)
        } catch (e: SecurityException) {
            e.printStackTrace()
        }
    }

    private fun allPhoto() {
        val intent = Intent()
        intent.action = Intent.ACTION_GET_CONTENT
        intent.type = "image/*"
        startActivityForResult(intent, 111)
    }

    private fun doPickImageFromSystem() {
        /**
         * 参数一:打开系统相册的ACTION
         * 参数二:返回数据的方式(从系统相册的数据库获取)
         */
        val intent = Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
        startActivityForResult(intent, PHOTO_ALBUM);
    }


    private fun takePhoto(){
        //构建一个ContentValues对象
        val values = ContentValues()
        values.put(MediaStore.MediaColumns.DISPLAY_NAME, "${System.currentTimeMillis()}.jpg")
        values.put(MediaStore.MediaColumns.MIME_TYPE, "image/jpeg")
        /* Android 10中新增了一个RELATIVE_PATH常量，表示文件存储的相对路径，可选值有DIRECTORY_DCIM、DIRECTORY_PICTURES、DIRECTORY_MOVIES、DIRECTORY_MUSIC等，
           分别表示相册、图片、电影、音乐等目录。而在之前的系统版本中并没有RELATIVE_PATH，所以我们要使用DATA常量（已在Android 10中废弃），
           并拼装出一个文件存储的绝对路径才行。*/
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DCIM)
        } else {
            values.put(MediaStore.MediaColumns.DATA, "${Environment.getExternalStorageDirectory().path}/${Environment.DIRECTORY_DCIM}/${System.currentTimeMillis()}.jpg")
        }
        val uri = contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
        //步骤四：调取系统拍照
        val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        /**
         * 通过相机拍照返回的Bitmap有两种方式:
         * 1.不传入MediaStore.EXTRA_OUTPUT时,直接由data返回一个缩略图
         * 2.当传入MediaStore.EXTRA_OUTPUT时,可以通过设置的图片保存路径来获取完整图片
         */
        //intent.putExtra(MediaStore.EXTRA_OUTPUT, uri)
        startActivityForResult(intent, CAMERA)
    }


    /**
     * 初始化定位参数配置
     */
    private fun initLocationOption() {
     //定位服务的客户端。宿主程序在客户端声明此类，并调用，目前只支持在主线程中启动
        locationClient = LocationClient(applicationContext)
        //声明LocationClient类实例并配置定位参数
        val locationOption = LocationClientOption()
        val myLocationListener = MyLocationListener()
        //注册监听函数
        locationClient.registerLocationListener(myLocationListener)
        //可选，默认高精度，设置定位模式，高精度，低功耗，仅设备
        locationOption.locationMode = LocationClientOption.LocationMode.Hight_Accuracy
        //可选，默认gcj02，设置返回的定位结果坐标系，如果配合百度地图使用，建议设置为bd09ll;
        locationOption.setCoorType("bd09ll")
        //可选，默认0，即仅定位一次，设置发起连续定位请求的间隔需要大于等于1000ms才是有效的
        locationOption.setScanSpan(1000)
        //可选，设置是否需要地址信息，默认不需要
        locationOption.isOpenGps=true
        locationOption.setIsNeedAddress(true)
        //可选，设置是否需要地址描述
        locationOption.setIsNeedLocationDescribe(true)
        //可选，设置是否需要设备方向结果
        locationOption.setNeedDeviceDirect(false)
        //可选，默认false，设置是否当gps有效时按照1S1次频率输出GPS结果
        locationOption.isLocationNotify = true
        //可选，默认true，定位SDK内部是一个SERVICE，并放到了独立进程，设置是否在stop的时候杀死这个进程，默认不杀死
        locationOption.setIgnoreKillProcess(true)
        //可选，默认false，设置是否需要位置语义化结果，可以在BDLocation.getLocationDescribe里得到，结果类似于“在北京天安门附近”
        locationOption.setIsNeedLocationDescribe(true)
        //可选，默认false，设置是否需要POI结果，可以在BDLocation.getPoiList里得到
        locationOption.setIsNeedLocationPoiList(true)
        //可选，默认false，设置是否收集CRASH信息，默认收集
        locationOption.SetIgnoreCacheException(false)
        //可选，默认false，设置是否开启Gps定位
        locationOption.isOpenGps = true
        //可选，默认false，设置定位时是否需要海拔信息，默认不需要，除基础定位版本都可用
        locationOption.setIsNeedAltitude(false)
        //设置打开自动回调位置模式，该开关打开后，期间只要定位SDK检测到位置变化就会主动回调给开发者，该模式下开发者无需再关心定位间隔是多少，定位SDK本身发现位置变化就会及时回调给开发者
        locationOption.setOpenAutoNotifyMode()
        //设置打开自动回调位置模式，该开关打开后，期间只要定位SDK检测到位置变化就会主动回调给开发者
        locationOption.setOpenAutoNotifyMode(3000, 1, LocationClientOption.LOC_SENSITIVITY_HIGHT)
        //需将配置好的LocationClientOption对象，通过setLocOption方法传递给LocationClient对象使用
        locationClient.locOption = locationOption
        //开始定位
        locationClient.start()
    }

    /**
     * 实现定位回调
     */
    class MyLocationListener : BDAbstractLocationListener() {
        override fun onReceiveLocation(location: BDLocation) {
            //此处的BDLocation为定位结果信息类，通过它的各种get方法可获取定位相关的全部结果
            //以下只列举部分获取经纬度相关（常用）的结果信息
            //更多结果信息获取说明，请参照类参考中BDLocation类中的说明
            //获取定位类型、定位错误返回码，具体信息可参照类参考中BDLocation类中的说明
            val errorCode = location.locType
            //获取纬度信息
            val latitude = location.latitude
            //获取经度信息
            val longitude = location.longitude
            //获取定位精度，默认值为0.0f
            val radius = location.radius
            //获取经纬度坐标类型，以LocationClientOption中设置过的坐标类型为准
            val coorType = location.coorType
            val addr = location.addrStr
            if (errorCode == 161 && addr!=null){
                XPopup.Builder(mContext).asConfirm("定位",addr, OnConfirmListener {

                }).show()
                locationClient.stop()
            }
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when(requestCode){
            CAMERA -> {
                if (resultCode == Activity.RESULT_OK && data != null) {
                    var bitmap: Bitmap = data?.extras?.get("data") as Bitmap
                    if (bitmap != null) {
                        imageView.setImageBitmap(bitmap)
                    }
                }
            }
            PHOTO_ALBUM -> {
                if (resultCode == Activity.RESULT_OK && data != null) {
                    var uri = data.data
                    imageView.setImageURI(uri)
                }
            }
        }
    }
}